package com.acg.auth.config;

import com.acg.auth.pojo.SysOperLog;
import com.acg.auth.service.SysOperLogService;
import com.acg.util.IPUtils;
import com.acg.util.JwtHelper;
import com.acg.util.OperLog;
import com.alibaba.fastjson.JSON;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @Description TODO
 * @Author 没有脑袋
 * @Date 2025/8/4 10:30
 */
@Aspect
@Component
@Slf4j
@Data
public class MyAopAspect {

    @Resource
    private SysOperLogService service;
    /**
     * 设置 拦截注解 @OperLog
     * annotation 拦截注解
     *  注解路径
     *
     *
     */
    @Pointcut("@annotation(com.acg.util.OperLog)")
    public void  pointcut(){
    }


    /**
     * 操作日志拦截
     * @param joinPoint
     * @throws Throwable
     */
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 1 创建 操作类
        SysOperLog operLog = new SysOperLog();
        // operLog.setMethod(joinPoint.getSignature().getName());   // 获取方法名
        //log.info("方法名:{}",joinPoint.getSignature().getName());
        System.out.println("方法名:"+"{"+joinPoint.getSignature().getName()+"}");
        // 获取request
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        // 获取token
        String token = request.getHeader("token");
        String username = JwtHelper.getUsername(token);   // 解析token获取用户名
        operLog.setOperName(username);      // 设置操作人

        //  operLog.setRequestMethod(joinPoint.getSignature().getDeclaringTypeName());
        operLog.setMethod(joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName());   // 方法名
        operLog.setOperUrl(request.getRequestURI());   // 请求地址
        operLog.setOperIp(IPUtils.getIpAddr(request));   // 请求ip
        // body
        // 获取方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method =signature.getMethod();       // 获取方法
        // 获取方法上 注解
        OperLog annotation = method.getAnnotation(OperLog.class);
        String value = annotation.value();  // 获取注解里面value值
//         log.info("注解value{}",value);
        // log.info("注解value:{}",value);
        System.out.println("注解value:"+"{"+value+"}");


        operLog.setTitle(value);

        // 获取请求的method  post put delete
        operLog.setRequestMethod(request.getMethod());

        // 获取参数
        String[] parameterNames = signature.getParameterNames();
        System.out.println(Arrays.toString(parameterNames));   // 获取参数名称
        Object[] args = joinPoint.getArgs();
        System.out.println("参数信息"+Arrays.toString(args));   // 获取参数值
        operLog.setOperParam(JSON.toJSONString( joinPoint.getArgs()));



        // 放行
        Object proceed = joinPoint.proceed();

        // 获取返回值
        operLog.setJsonResult(JSON.toJSONString(proceed));

        service.save(operLog);
        System.out.println("执行完方法"+operLog);

        // 放行 响应
        return proceed;

    }

}
